#include "testwidget.h"
#include "ui_testwidget.h"
#include <QMessageBox>
#include <QDebug>

TestWidget::TestWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::testWidget)
{
    ui->setupUi(this);
    serialPortInit();
}

TestWidget::~TestWidget()
{
    delete ui;
}


void TestWidget::serialPortInit()
{
    serialPort = new QSerialPort(this);
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
        ui->comboBox->addItem(info.portName());
    }
    ui->btnOpen->setText("打开串口");
    connect(serialPort,SIGNAL(readyRead()),this,SLOT(serialPortReadyRead()));

    serialTimer = new QTimer(this);
    serialTimer->setSingleShot(true);
    connect(serialTimer,&QTimer::timeout,this,&TestWidget::serialTimerTimeoutHandle);
}

bool TestWidget::isPrintableAscii(const QByteArray &data)
{
    for(char c : data) {
        // 允许空格(32)到波浪号(126)的标准ASCII可打印字符
        if(static_cast<unsigned char>(c) < 32 ||
           static_cast<unsigned char>(c) > 126) {
            return false;
        }
    }
    return !data.isEmpty();
}

void TestWidget::on_btnOpen_clicked(bool checked)
{
    if(ui->btnOpen->text() == "打开串口"){
        serialPort->setPortName(ui->comboBox->currentText());
        serialPort->setBaudRate(115200);
        serialPort->setDataBits(QSerialPort::Data8);
        serialPort->setParity(QSerialPort::NoParity);
        serialPort->setStopBits(QSerialPort::OneStop);
        /* 设置停止位 */
        serialPort->setFlowControl(QSerialPort::NoFlowControl);
        if(!serialPort->open(QIODevice::ReadWrite))
        {
            QMessageBox::about(NULL,"错误","串口无法打开！可能串口已经被占用");
            qDebug()<<"name: "<<serialPort->portName()<<" error: "<<serialPort->errorString()<<endl;
        }
        else{
            ui->comboBox->setEnabled(false);
            ui->btnOpen->setText("关闭串口");
        }
    }else{
        serialPort->close();
        ui->comboBox->setEnabled(true);
        ui->btnOpen->setText("打开串口");
    }
}

void TestWidget::on_btnSend_clicked(bool checked)
{
    QByteArray oriByte= ui->sendText->toPlainText().toUtf8();
    QByteArray senByte;
    senByte[0]=0xaa;
    senByte[1]=oriByte.size()+2;
    senByte[2]=0xc1;
    senByte.append(oriByte);
    senByte.append(0xff);

    serialPort->write(senByte);

    sha256_init(&ctx);
    sha256_update(&ctx, reinterpret_cast<BYTE*>(oriByte.data()), oriByte.size());
    BYTE buf[SHA256_BLOCK_SIZE];
    sha256_final(&ctx, buf);

    QByteArray hashBytes(reinterpret_cast<char*>(buf), SHA256_BLOCK_SIZE);
    QString hexHash = hashBytes.toHex().toUpper();
    ui->textBrowser->append("计算哈希: "+hexHash+ "\n");

}

void TestWidget::serialPortReadyRead()
{
    serialTimer->start(50);
}


//aa len cmd xxxxxx ff
void TestWidget::serialTimerTimeoutHandle()
{
    QByteArray buf = serialPort->readAll();

    if((quint8)buf.at(0) !=0xaa)
    {
        qDebug()<<"error head :"<<buf<<endl;
    }

    if(buf.size() <3)
    {
        qDebug()<<"error length :"<<buf<<endl;
    }

    if((quint8)buf.at(2) == 0xc1)
    {
        //认为是hash计算
        QByteArray hashByte = buf.mid(3,(quint8)buf.at(1)-2);
        QByteArray hashBytes(hashByte, SHA256_BLOCK_SIZE);
        QString hexHash = hashBytes.toHex().toUpper();
        ui->textBrowser->append("mcu反馈 : "+hexHash+ "\n");
    }


    if((quint8)buf.at(2) == 0xc2)
    {
        //认为是rsa计算
        QByteArray hashByte = buf.mid(3,(quint8)buf.at(1)-2);
//        QByteArray hashBytes(hashByte, SHA256_BLOCK_SIZE);
        QString hexHash = hashByte,data();
        ui->textBrowser->append("mcu反馈 : "+hexHash+ "\n");
    }

//    // 自动判断内容类型
//    if(isPrintableAscii(buf)) {
//        // 可读文本直接转换
//        QString text = QString::fromUtf8(buf).trimmed();
//        ui->textBrowser->append(text + "\n");  // 添加换行
//    } else {
//        // 二进制数据转HEX格式显示
//        QString hexText = buf.toHex(' ').toUpper();
//        ui->textBrowser->append("[HEX] " + hexText + "\n");
//    }
}

void TestWidget::on_btnRsaSend_clicked(bool checked)
{
    pub = { 0x045AD697, 0x4299D7DB};
    priv = { 0x044AD69F ,0x63D5590B};
//    rsa_gen_keys(&pub, &priv);

//    qDebug()<<"generate pbu priv"<<endl;
    // 将二进制哈希值转换为HEX字符串
//    QByteArray hashBytes(reinterpret_cast<char*>(buf), SHA256_BLOCK_SIZE);
//    QString hexHash = hashBytes.toHex().toUpper();
//    qDebug() << "SHA256哈希值:" << hexHash;

    unsigned int cw[64] = {0}; // 需要两倍空间存储加密结果
    QByteArray oriByte= ui->sendText->toPlainText().toUtf8();
    rsa_encrypt(priv,oriByte.data(),oriByte.size(), cw);
//      rsa_encrypt(priv,"12345678",8, cw);

    // 将unsigned int数组转换为字节数组
    QByteArray encryptedBytes;
    for(int i = 0; i < 64; i++) {
        if (!cw[i]) break;
        encryptedBytes.append(static_cast<char>((cw[i] >> 24) & 0xFF));// 最高位字节
        encryptedBytes.append(static_cast<char>((cw[i] >> 16) & 0xFF));// 次高位
        encryptedBytes.append(static_cast<char>((cw[i] >> 8) & 0xFF)); // 次低位
        encryptedBytes.append(static_cast<char>(cw[i] & 0xFF));         // 最低位字节
    }

    QByteArray senByte;
    senByte.append(0xaa);  // 使用append替代直接索引赋值
    senByte.append(static_cast<char>(encryptedBytes.size() + 2)); // 长度字段
    senByte.append(0xc2);  // 命令字
    senByte.append(encryptedBytes); // 添加加密数据
    senByte.append(0xff);  // 结束符
    qDebug()<<"sendByte: "<<senByte<<endl;
    serialPort->write(senByte);

}
